package gui.controller;

import gui.view.SolutionInfo;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import solverLogic.Solver;
import dataTypes.Sudoku;

/**
 * 
 * @author Felix Schliephacke
 * 
 * @param <T>
 */
public class SolveSupport<T> extends Thread implements PropertyChangeListener {

	private Sudoku<T> oldSudoku;
	private SolutionInfo<T> solutionInfo;
	private Solver<T> solver;
	private PropertyChangeSupport support;

	public SolveSupport(final Sudoku<T> sudoku) {
		this.solutionInfo = new SolutionInfo<T>(this);
		this.support = new PropertyChangeSupport(this);
		this.oldSudoku = sudoku.clone();
		this.solver = Solver.getInstance(this.oldSudoku);
		this.solver.addPropertyChangeListener(this.solutionInfo);
		this.start();
	}

	public void addPropertyChangeListener(final PropertyChangeListener listener) {
		if (this.support != null) {
			this.support.addPropertyChangeListener(listener);
		}
	}

	@Override
	protected void finalize() {
		this.oldSudoku = null;
		this.solutionInfo = null;
		this.solver = null;
		this.support = null;
	}

	public int getSolutionCount() {
		return Solver.getSolutionCount();
	}

	@Override
	public void interrupt() {
		if (this.solver != null) {
			this.solver.interrupt();
		}
	}

	@Override
	public void propertyChange(final PropertyChangeEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void removePropertyChangeListener(
			final PropertyChangeListener listener) {
		if (this.support != null) {
			this.support.removePropertyChangeListener(listener);
		}
	}

	@Override
	public void run() {
		this.solver.init();
		try {
			this.solver.join();
		} catch (final InterruptedException e) {
		}
		this.support.firePropertyChange(PropertyChangeConstants.SOLVED
				.toString(), this.oldSudoku, this.solver.getSolutions());
		this.solver.removePropertyChangeListener(this.solutionInfo);
		this.finalize();
	}
}
